package com.zyk.scaffold.tcp.connector;

import com.zyk.scaffold.common.utils.AssertUtil;
import com.zyk.scaffold.tcp.proto3.MessageBuf;
import com.zyk.scaffold.tcp.session.Session;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TcpConnection implements Connection {
    private ChannelHandlerContext cxt;
    protected Session session = null;

    public static Connection created(ChannelHandlerContext cxt, Session session) {
        TcpConnection tcpConnection = new TcpConnection();
        tcpConnection.cxt = cxt;
        tcpConnection.session = session;
        return tcpConnection;
    }

    @Override
    public void refreshChannelHandlerContext(ChannelHandlerContext ctx) {
        this.cxt = ctx;
    }

    @Override
    public void send(String sessionId, MessageBuf.JMTransfer message) {
        try {
            ChannelFuture cf = cxt.writeAndFlush(message);
            cf.addListener((future) -> {
                if (future.isSuccess()) {
                    log.debug("send success.");
                } else {
                    AssertUtil.error("Failed to send message.");
                }
                Throwable cause = future.cause();
                if (cause != null) {
                    AssertUtil.error("Failed to send message.", cause);
                }
            });
        } catch (Exception e) {
            AssertUtil.error("TcpConnection pushMessage occur Exception.", e);
            log.error("TcpConnection pushMessage occur Exception.", e);
        } catch (Throwable e) {
            AssertUtil.error("TcpConnection pushMessage occur Throwable.", e);
            log.error("TcpConnection pushMessage occur Throwable.", e);
        }
    }

    @Override
    public void close() {
        this.session.close();
        this.cxt.close();
        this.session = null;
        this.session = null;
        this.cxt = null;
    }
}
